﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace vs2017离线安装操作
{
    // 1.定义委托
    public delegate void DelReadStdOutput(string result);
    public delegate void DelReadErrOutput(string result);
    public partial class MainForm : Form
    {
        // 2.定义委托事件
        public event DelReadStdOutput ReadStdOutput;
        public event DelReadErrOutput ReadErrOutput;

        string baseFromPath = "https://aka.ms/vs/15/release/";
        string baseDownPath = System.Environment.CurrentDirectory;

        /// <summary>
        /// 节点实体
        /// </summary>
        class DicNode
        {

            private string parentname;
            private string name;
            private string text;
            private string tooltip;
            private bool ischecked;

            /// <summary>
            /// 父节点名称
            /// </summary>
            public string Parentname { get => parentname; set => parentname = value; }
            /// <summary>
            /// 名称
            /// </summary>
            public string Name { get => name; set => name = value; }
            /// <summary>
            /// 显示名称
            /// </summary>
            public string Text { get => text; set => text = value; }
            /// <summary>
            /// 提示信息
            /// </summary>
            public string Tooltip { get => tooltip; set => tooltip = value; }
            /// <summary>
            /// 是否勾选
            /// </summary>
            public bool Ischecked { get => ischecked; set => ischecked = value; }
        }

        /// <summary>
        /// 工作负载列表
        /// </summary>
        List<DicNode> workloadList = new List<DicNode>()
        {
            //核心编辑器默认选择
            new DicNode{Name="CoreEditor",Text="Visual Studio 核心编辑器",Tooltip="Visual Studio 核心 shell 体验，包括语法感知代码编辑、源代码管理和工作项管理。",Ischecked=true },
            new DicNode{Name= "Azure",Text="Azure 开发",Tooltip="用于开发云应用、创建资源以及生成包括 Docker 支持的容器的 Azure SDK、工具和项目。" },
            new DicNode{Name= "Data",Text="数据存储和处理",Tooltip="使用 SQL Server、Azure Data Lake 或 Hadoop 连接、开发和测试数据解决方案。" },
            new DicNode{Name= "DataScience",Text="数据科学和分析应用程序",Tooltip="用于创建数据科学应用程序的语言和工具（包括 Python、R 和 F#）。" },
            new DicNode{Name= "ManagedDesktop",Text=".NET 桌面开发",Tooltip="使用 C#、Visual Basic 和 F# 生成 WPF、Windows 窗体和控制台应用程序。" },
            new DicNode{Name= "ManagedGame",Text="使用 Unity 的游戏开发",Tooltip="使用 Unity（功能强大的跨平台开发环境）创建 2D 和 3D 游戏。" },
            new DicNode{Name= "NativeCrossPlat",Text="使用 C++ 的 Linux 开发",Tooltip="创建和调试在 Linux 环境中运行的应用程序。" },
            new DicNode{Name= "NativeDesktop",Text="使用 C++ 的桌面开发",Tooltip="使用 Microsoft C++ 工具集、ATL 或 MFC 生成 Windows 桌面应用程序。" },
            new DicNode{Name= "NativeGame",Text="使用 C++ 的游戏开发",Tooltip="以 DirectX、Unreal 或 Cocos2d 为后盾，利用 C++ 的强大功能生成专业游戏。" },
            new DicNode{Name= "NativeMobile",Text="使用 C++ 的移动开发",Tooltip="使用 C++ 生成适用于 iOS、Android 或 Windows 的跨平台应用程序。" },
            new DicNode{Name= "NetCoreTools",Text=".NET Core 跨平台开发",Tooltip="使用 .NET Core、ASP.NET Core、HTML/JavaScript 和包括 Docker 支持的容器生成跨平台应用程序。" },
            new DicNode{Name= "NetCrossPlat",Text="使用 .NET 的移动开发",Tooltip="使用 Xmarin 生成适用于 iOS、Android 或 Windows 的跨平台应用程序。" },
            new DicNode{Name= "NetWeb",Text="ASP.NET 和 Web 开发",Tooltip="使用 ASP.NET、ASP.NET Core、HTML/JavaScript 和包括 Docker 支持的容器生成 Web 应用程序。" },
            new DicNode{Name= "Node",Text="Node.js 开发",Tooltip="使用 Node.js（事件驱动的异步 JavaScript 运行时）生成可扩展的网络应用程序。" },
            new DicNode{Name= "Office",Text="Office/SharePoint 开发",Tooltip="使用 C#、VB 和 JavaScript 创建 Office 和 SharePoint 外接程序、SharePoint 解决方案和 VSTO 外接程序。" },
            new DicNode{Name= "Python",Text="Python 开发",Tooltip="适用于 Python 的编辑、调试、交互式开发和源代码管理。" },
            new DicNode{Name= "Universal",Text="通用 Windows 平台开发",Tooltip="使用 C#、VB 和 JavaScript 或 C++（可选）创建适用于通用 Windows 平台的应用程序。" },
            new DicNode{Name= "VisualStudioExtension",Text="Visual Studio 扩展开发",Tooltip="创建适用于 Visual Studio 的加载项和扩展，包括新命令、代码分析器和工具窗口。" },
            new DicNode{Name= "WebCrossPlat",Text="使用 JavaScript 的移动开发",Tooltip="使用用于 Apache Cordova 的工具生成 Android、iOS 和 UWP 应用。" },
            new DicNode{Name= "Others",Text="独立组件",Tooltip="这些组件不随附于任何工作负载，但可选择作为单个组件。" }
        };

        /// <summary>
        /// 组件列表
        /// </summary>
        List<DicNode> componentList = new List<DicNode>()
        {
            new DicNode{Parentname= "Others",Name="Component.Android.Emulator",Text="适用于 Android 的 Visual Studio 仿真程序"},
            new DicNode{Parentname= "Others",Name="Component.Android.NDK.R11C",Text="Android NDK (R11C)"},
            new DicNode{Parentname= "Others",Name="Component.Android.NDK.R11C_3264",Text="Android NDK (R11C)（32 位）"},
            new DicNode{Parentname= "Others",Name="Component.Android.SDK23",Text="Android SDK 安装程序（API 级别 23）（全局安装）"},
            new DicNode{Parentname= "Others",Name="Component.Android.SDK25",Text="Android SDK 安装程序（API 级别 25）"},
            new DicNode{Parentname= "Others",Name="Component.GitHub.VisualStudio",Text="适用于 Visual Studio 的 GitHub 扩展"},
            new DicNode{Parentname= "Others",Name="Component.Google.Android.Emulator.API23.V2",Text="Google Android Emulator（API 级别 23）（全局安装）"},
            new DicNode{Parentname= "Others",Name="Component.Google.Android.Emulator.API25",Text="Google Android Emulator（API 级别 25）"},
            new DicNode{Parentname= "Others",Name="Microsoft.Component.Blend.SDK.WPF",Text="用于 .NET 的 Blend for Visual Studio SDK "},
            new DicNode{Parentname= "Others",Name="Microsoft.Component.HelpViewer",Text="帮助查看器"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.LinqToSql",Text="LINQ to SQL 工具"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.Phone.Emulator Windows",Text="10 移动版仿真程序（周年纪念版）"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.Phone.Emulator.15063",Text="Windows 10 Mobile 仿真器（创意者更新）"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.Runtime.Node.x86.6.4.0",Text="基于 Node.js v6.4.0 (x86) 的组件运行时"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.Runtime.Node.x86.7.4.0",Text="基于 Node.js v7.4.0 (x86) 的组件运行时"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TestTools.CodedUITest",Text="编码的 UI 测试"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TestTools.FeedbackClient",Text="Microsoft Feedback Client"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TestTools.MicrosoftTestManager Microsoft",Text="测试管理器"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TypeScript.2.0",Text="TypeScript 2.0 SDK"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TypeScript.2.1",Text="TypeScript 2.1 SDK"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TypeScript.2.2",Text="TypeScript 2.2 SDK"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TypeScript.2.5",Text="TypeScript 2.5 SDK"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TypeScript.2.6",Text="TypeScript 2.6 SDK"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.TypeScript.2.7",Text="TypeScript 2.7 SDK"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.UWP.VC.ARM64",Text="适用于 ARM64 的 C++ 通用 Windows 平台工具"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.ATL.ARM.Spectre",Text="带有 Spectre 缓解措施的 Visual C++ ATL for ARM"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre",Text="带有 Spectre 缓解措施的 Visual C++ ATL for ARM64"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.ATL.Spectre",Text="带有 Spectre 缓解措施的 Visual C++ ATL (x86/x64)"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.ATLMFC.Spectre",Text="带有 Spectre 缓解措施的 Visual C++ MFC for x86/x64"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.ClangC2",Text="Clang/C2（实验）"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.MFC.ARM",Text="Visual C++ MFC for ARM"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.MFC.ARM.Spectre",Text="带有 Spectre 缓解措施的 Visual C++ MFC for ARM"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.MFC.ARM64",Text="Visual C++ MFC for ARM64"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.MFC.ARM64.Spectre",Text="带有 Spectre 缓解措施的针对 ARM64 的 Visual C++ MFC 支持"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.Runtimes.ARM.Spectre",Text="面向 Spectre 的 VC++ 2017 版本 15.7 v14.14 库 (ARM)"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre",Text="面向 Spectre 的 VC++ 2017 版本 15.7 v14.14 库 (ARM64)"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre",Text="面向 Spectre 的 VC++ 2017 版本 15.7 v14.14 库 (x86 和 x64)"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.Tools.14.11",Text="VC++ 2017 版本 15.4 v14.11 工具集"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.Tools.14.12",Text="VC++ 2017 版本 15.5 v14.12 工具集"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.Tools.14.13",Text="VC++ 2017 版本 15.6 v14.13 工具集"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.VC.Tools.ARM64",Text="用于 ARM64 的 Visual C++ 编译器和库"},
            new DicNode{Parentname= "Others",Name="Microsoft.VisualStudio.Component.Windows10SDK.16299.Desktop.arm",Text="适用于桌面 C++ [ARM 和 ARM64] 的 Windows 10 SDK"}
        };


        public MainForm()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            //3.将相应函数注册到委托事件中
            ReadStdOutput += new DelReadStdOutput(ReadStdOutputAction);
            ReadErrOutput += new DelReadErrOutput(ReadErrOutputAction);
        }

        /// <summary>
        /// 窗体显示时操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Shown(object sender, EventArgs e)
        {
            if (Properties.Settings.Default["程序版本"].ToString() != "")
            {
                comboBox1.SelectedItem = Properties.Settings.Default["程序版本"].ToString();
            }
            if (Properties.Settings.Default["缓存目录"].ToString() != "")
            {
                txtSaveDirectory.Text = Properties.Settings.Default["缓存目录"].ToString();
            }
            string checkworkloadstr = "";
            string checkcomponentstr = "";
            if(Properties.Settings.Default["选择负载"].ToString() != "")
            {
                checkworkloadstr = Properties.Settings.Default["选择负载"].ToString();
            }
            if (Properties.Settings.Default["选择组件"].ToString() != "")
            {
                checkcomponentstr = Properties.Settings.Default["选择组件"].ToString();
            }

            treeViewWorkload.Nodes.Clear();
            foreach (DicNode dicnode in workloadList)
            {
                TreeNode treenode = new TreeNode();
                treenode.Name = dicnode.Name;
                treenode.Text = dicnode.Text;
                treenode.ToolTipText = dicnode.Tooltip;

                if(checkworkloadstr.IndexOf(dicnode.Name)>-1)
                {
                    dicnode.Ischecked = true;
                    treenode.Checked = true;
                }

                if (dicnode.Name == "CoreEditor")
                {
                    treenode.Checked = true;
                }
                if (dicnode.Name == "Others")
                {
                    int checkednum = 0;
                    foreach (DicNode tempdicnode in componentList)
                    {
                        TreeNode childnode = new TreeNode();
                        childnode.Name = tempdicnode.Name;
                        childnode.Text = tempdicnode.Text;
                        childnode.ToolTipText = tempdicnode.Tooltip;
                        treenode.Nodes.Add(childnode);

                        if (checkcomponentstr.IndexOf(tempdicnode.Name) > -1)
                        {
                            tempdicnode.Ischecked = true;
                            childnode.Checked = true;
                            checkednum++;
                        }
                    }

                    if(treenode.Nodes.Count!=checkednum)
                    {
                        treenode.Checked = false;
                        dicnode.Ischecked = false;
                    }

                }
                treeViewWorkload.Nodes.Add(treenode);
            }
        }


        /// <summary>
        /// 控制节点选中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeViewWorkload_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            //VS2017的核心组件，必选
            if (e.Node.Name == "CoreEditor")
            {
                if (!e.Node.Checked)
                {
                    e.Node.Checked = true;
                }
            }
            else
            {
                if (e.Node.Nodes.Count > 0)
                {
                    foreach (TreeNode node in e.Node.Nodes)
                    {
                        node.Checked = e.Node.Checked;
                    }

                    List<DicNode> tempcomponentList= componentList.Where(a => a.Parentname == e.Node.Name).ToList();
                    foreach(DicNode node in tempcomponentList)
                    {
                        node.Ischecked = e.Node.Checked;
                    }
                }

                if(e.Node.Parent!=null)
                {
                    int childcount = e.Node.Parent.Nodes.Count;
                    int checkedcount = 0;
                    foreach(TreeNode node in e.Node.Parent.Nodes)
                    {
                        if(node.Checked)
                        {
                            checkedcount++;
                        }
                    }

                    if(childcount==checkedcount)
                    {
                        e.Node.Parent.Checked = true;
                    }
                    else
                    {
                        e.Node.Parent.Checked = false;
                    }
                }

                DicNode dicnode = workloadList.Find(a => a.Name == e.Node.Name);
                if (dicnode != null)
                {
                    dicnode.Ischecked = e.Node.Checked;
                }
                dicnode = componentList.Find(a => a.Name == e.Node.Name);
                if (dicnode != null)
                {
                    dicnode.Ischecked = e.Node.Checked;
                }

            }
        }

        /// <summary>
        /// 根据下拉选项判断文件名称
        /// </summary>
        /// <returns></returns>
        string getFileNameByTypeCombox()
        {
            string fromPath = "";
            string typestr = comboBox1.SelectedItem.ToString();
            if (typestr == "Visual Studio Community 2017")
            {
                fromPath = "vs_community.exe";
            }
            else if (typestr == "Visual Studio Professional 2017")
            {
                fromPath = "vs_professional.exe";
            }
            else if (typestr == "Visual Studio Enterprise 2017")
            {
                fromPath = "vs_enterprise.exe";
            }

            return fromPath;
        }


        public delegate string MyDelegate();

        /// <summary>
        /// 执行命令
        /// </summary>
        /// <param name="StartCmd"></param>
        private void RealAction(string StartCmd)
        {
            Process CmdProcess = new Process();

            CmdProcess.StartInfo.FileName = "cmd.exe";          // 命令
            //CmdProcess.StartInfo.Arguments = StartFileArg;    // 参数
            CmdProcess.StartInfo.WorkingDirectory = ".";

            CmdProcess.StartInfo.CreateNoWindow = true;         // 不创建新窗口
            CmdProcess.StartInfo.UseShellExecute = false;       // 是否使用shell
            CmdProcess.StartInfo.RedirectStandardInput = true;  // 重定向输入
            CmdProcess.StartInfo.RedirectStandardOutput = true; // 重定向标准输出
            CmdProcess.StartInfo.RedirectStandardError = true;  // 重定向错误输出
            //CmdProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            CmdProcess.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
            CmdProcess.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);

            CmdProcess.EnableRaisingEvents = true;                      // 启用Exited事件
            CmdProcess.Exited += new EventHandler(CmdProcess_Exited);   // 注册进程结束事件

            CmdProcess.Start();

            //输入命令
            CmdProcess.StandardInput.WriteLine(StartCmd);

            CmdProcess.BeginOutputReadLine();
            CmdProcess.BeginErrorReadLine();

            // 如果打开注释，则以同步方式执行命令，此例子中用Exited事件异步执行。
            // CmdProcess.WaitForExit();     
        }

        private void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                // 4. 异步调用，需要invoke
                this.Invoke(ReadStdOutput, new object[] { e.Data });
            }
        }

        private void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                this.Invoke(ReadErrOutput, new object[] { e.Data });
            }
        }

        /// <summary>
        /// 输出命令信息
        /// </summary>
        /// <param name="result"></param>
        private void ReadStdOutputAction(string result)
        {
            this.txtcmdLogTextArea.AppendText(result + "\r\n");
        }

        /// <summary>
        /// 输出错误信息
        /// </summary>
        /// <param name="result"></param>
        private void ReadErrOutputAction(string result)
        {
            //this.textBoxShowErrRet.AppendText(result + "\r\n");
        }

        private void CmdProcess_Exited(object sender, EventArgs e)
        {
            // 执行结束后触发

        }

        /// <summary>
        /// 选择程序版本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

            DirectoryInfo di = new DirectoryInfo(System.Environment.CurrentDirectory);
            FileInfo[] files = di.GetFiles(getFileNameByTypeCombox());

            if (files.Length > 0)
            {
                linkDown.Visible = false;
            }
            else
            {
                linkDown.Visible = true;
            }
        }


        /// <summary>
        /// 选择缓存目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectDir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.ShowNewFolderButton = true;
            DialogResult result = fbd.ShowDialog();

            if (result == DialogResult.OK)
            {
                txtSaveDirectory.Text = fbd.SelectedPath;
            }
        }

        /// <summary>
        /// 下载指定版本官方工具
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void linkDown_Click(object sender, EventArgs e)
        {
            string fromPath = baseFromPath + getFileNameByTypeCombox();
            string savePath = baseDownPath + "\\" + getFileNameByTypeCombox();

            DownFile df = new DownFile(fromPath, savePath);
            df.StartPosition = FormStartPosition.CenterParent;
            DialogResult result = df.ShowDialog();
            if (result == DialogResult.OK)
            {
                comboBox1_SelectedIndexChanged(null, null);
                MessageBoxEx.Show("下载成功！");
            }
        }

        /// <summary>
        /// 保存设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            string configFileName = Application.ExecutablePath + ".config";
            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            doc.Load(configFileName);
            string configString = @"configuration/applicationSettings/vs2017离线安装操作.Properties.Settings/setting[@name='程序版本']/value";
            System.Xml.XmlNode configNode = doc.SelectSingleNode(configString);
            if (configNode != null)
            {
                if (comboBox1.SelectedIndex > -1)
                {
                    configNode.InnerText = comboBox1.SelectedItem.ToString();
                    doc.Save(configFileName);
                }
            }

            configString = @"configuration/applicationSettings/vs2017离线安装操作.Properties.Settings/setting[@name='缓存目录']/value";
            configNode = doc.SelectSingleNode(configString);
            if (configNode != null)
            {
                configNode.InnerText = txtSaveDirectory.Text.Trim();
                doc.Save(configFileName);
                // 刷新应用程序设置，这样下次读取时才能读到最新的值。
                Properties.Settings.Default.Reload();
            }

            string str = "";
            List<DicNode> checklist = null;
            configString = @"configuration/applicationSettings/vs2017离线安装操作.Properties.Settings/setting[@name='选择负载']/value";
            configNode = doc.SelectSingleNode(configString);
            if (configNode != null)
            {
                str = "";
                checklist = workloadList.Where(a => a.Ischecked == true).ToList();
                foreach(DicNode dicnode in checklist)
                {
                    if(str!="")
                    {
                        str += "|";
                    }
                    str += dicnode.Name;
                }

                configNode.InnerText = str;
                doc.Save(configFileName);
                // 刷新应用程序设置，这样下次读取时才能读到最新的值。
                Properties.Settings.Default.Reload();
            }

            configString = @"configuration/applicationSettings/vs2017离线安装操作.Properties.Settings/setting[@name='选择组件']/value";
            configNode = doc.SelectSingleNode(configString);
            if (configNode != null)
            {
                str = "";
                checklist = componentList.Where(a => a.Ischecked == true).ToList();
                foreach (DicNode dicnode in checklist)
                {
                    if (str != "")
                    {
                        str += "|";
                    }
                    str += dicnode.Name;
                }

                configNode.InnerText = str;
                doc.Save(configFileName);
                // 刷新应用程序设置，这样下次读取时才能读到最新的值。
                Properties.Settings.Default.Reload();
            }

            //程序运行后只有操作xml方式才能修改配置文件
            //if (comboBox1.SelectedIndex > -1)
            //{
            //    Properties.Settings.Default.["程序版本"] = comboBox1.SelectedItem.ToString();
            //}
            //else
            //{
            //    Properties.Settings.Default["程序版本"] = "";
            //}

            //Properties.Settings.Default["缓存目录"] = txtSaveDirectory.Text.Trim();
            //Properties.Settings.Default.Save();


            MessageBoxEx.Show(this, "保存成功", "提示");
        }

        /// <summary>
        /// 根据设置生成命令
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBuild_Click(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex == -1)
            {
                MessageBoxEx.Show(this, "请选择程序版本", "提示");
                return;
            }
            else
            {
                if (linkDown.Visible)
                {
                    MessageBoxEx.Show(this, "请先下载相关程序", "提示");
                    return;
                }
            }
            if (txtSaveDirectory.Text.ToString() == "")
            {
                MessageBoxEx.Show(this, "请选择缓存目录", "提示");
                return;
            }
            else
            {
                if (!Directory.Exists(txtSaveDirectory.Text.Trim()))
                {
                    MessageBoxEx.Show(this, "缓存目录不存在，请检查后重试", "提示");
                    return;
                }
            }


            //挑选组件
            List<DicNode> checkedworkloadList = workloadList.Where(a => a.Ischecked == true).ToList();
            List<DicNode> checkedcomponentList = componentList.Where(a => a.Ischecked == true).ToList();

            if (checkedworkloadList.Count == 1 && checkedcomponentList.Count == 0)
            {
                DialogResult result = MessageBoxEx.Show("是否确认只安装核心组件?", "提示", MessageBoxButtons.YesNo);
                if (result == DialogResult.No)
                {
                    return;
                }
            }
            
            string includestr = "";
            foreach (DicNode dicnode in checkedworkloadList)
            {
                //其他组件分开处理
                if(dicnode.Name=="Others")
                {
                    List<DicNode> others = componentList.Where(a => a.Parentname == "Others").ToList();
                    checkedcomponentList = checkedcomponentList.Concat(others).ToList();
                }
                else
                {
                    includestr += "--add Microsoft.VisualStudio.Workload." + dicnode.Name + " ";
                }
            }
            foreach (DicNode dicnode in checkedcomponentList)
            {
                includestr += "--add " + dicnode.Name + " ";
            }

            if (includestr != "")
            {
                includestr += "--includeRecommended ";
            }


            //默认缓存中文版全部组件
            string cmdstr = getFileNameByTypeCombox() + " --layout " + txtSaveDirectory.Text.Trim() + " " + includestr + " --lang Zh-cn";

            txtcmdLogTextArea.Text = cmdstr;
        }

        /// <summary>
        /// 开始缓存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDown_Click(object sender, EventArgs e)
        {
            RealAction(txtcmdLogTextArea.Text);
        }

        /// <summary>
        /// 清理旧数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void linkClean_Click(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex == -1)
            {
                MessageBoxEx.Show(this, "请选择程序版本", "提示");
                return;
            }
            else
            {
                if (linkDown.Visible)
                {
                    MessageBoxEx.Show(this, "请先下载相关程序", "提示");
                    return;
                }
            }

            if (txtSaveDirectory.Text.ToString() == "")
            {
                MessageBoxEx.Show(this, "请选择缓存目录", "提示");
                return;
            }
            else
            {
                if (!Directory.Exists(txtSaveDirectory.Text.Trim()))
                {
                    MessageBoxEx.Show(this, "缓存目录不存在，请检查后重试", "提示");
                    return;
                }
            }

            //获取最新目录的名称
            string cleanpath = "";

            //判断根目录
            DirectoryInfo di = new DirectoryInfo(txtSaveDirectory.Text.ToString());
            DirectoryInfo[] dilist = di.GetDirectories("Archive");
            if (dilist.Length == 0)
            {
                MessageBoxEx.Show(this, "当前缓存目录下文件无需清理", "提示");
                return;
            }

            //判断指定目录
            di = dilist[0];
            dilist = di.GetDirectories();

            if (dilist.Length == 0)
            {
                MessageBoxEx.Show(this, "当前缓存目录下文件无需清理", "提示");
                return;
            }
            else
            {
                if (dilist.Length > 1)
                {
                    MessageBoxEx.Show("当前目录存在多个旧文件记录，请选择指定文件夹下Catalog.json文件，清理旧文件", "提示");
                    OpenFileDialog ofd = new OpenFileDialog();
                    ofd.InitialDirectory = txtSaveDirectory.Text + "\\Archive";
                    ofd.Multiselect = false;
                    DialogResult result = ofd.ShowDialog();
                    if (result == DialogResult.OK)
                    {
                        cleanpath = ofd.FileName;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    //获取最新目录的名称
                    cleanpath = txtSaveDirectory.Text.Trim() + "\\Archive\\" + dilist[0].Name + "\\Catalog.json";
                }

                string cmdstr = getFileNameByTypeCombox() + " --layout " + txtSaveDirectory.Text.Trim() + " --clean " + cleanpath;
                RealAction(cmdstr);
            }
        }


    }
}
